用 Grill 把 Vibe Coding 从“直接写代码”变成工程流程
基于 Matt Pocock(AI Hero)的 7 节 AI Skills 邮件课程及对应 Skill 指南整理。
一、先理解核心:不要把 Vibe Coding 等同于“让 AI 写代码”
Vibe Coding 真正需要解决的不是生成速度,而是以下五个工程问题:
- 方向是否明确:需求模糊时,Agent 依然会产出代码,但很可能是在快速实现错误答案。
- 未知是否被验证:交互、状态模型和第三方能力,有些问题靠讨论无法确定。
- 任务是否适合上下文窗口:Agent 一次承担太多内容,后半段往往会遗忘约束。
- 执行是否可控制:后台 Agent 必须隔离、可观察、可停止、可审查。
- 经验是否能进入下一轮:只修当前 Diff,不改善文档、验证和架构,下次仍会犯同样的错。
因此,完整工作流不是“一句话需求 → 生成代码”,而是:
澄清 → 必要时原型验证 → 固化决策 → 拆分任务 → 隔离执行 → 双轴审查 → 改进工作系统
这套方法的目标也不只是完成一个功能,而是让每轮执行结束后同时得到:
- 可工作的代码;
- 更清楚的业务语言与决策记录;
- 更可靠的验证方法;
- 更适合后续 Agent 理解的代码结构。
二、先判断任务规模,不要每次跑完整流程
路径 A:小型、明确任务
适合:文案调整、样式修复、已定位 Bug、简单接口字段变更。
读取相关代码 → 明确验收条件 → 实现 → 测试 → 审查 Diff
不需要 Spec、Tickets 或 Prototype。完整流程会增加成本,反而可能在多次转述中发生语义漂移。
路径 B:中型功能,方向基本明确
适合:单页面功能、局部重构、一个上下文窗口内可以完成的需求。
Grill → Implement → Code Review
如果讨论中出现无法仅靠语言解决的问题,再临时进入 Prototype 分支。
路径 C:跨会话工作
这里必须区分“实现跨会话”和“规划本身跨会话”:
规划能在一个会话完成,只有实现跨会话:
Grill → Prototype(按需)→ Spec → Tickets → 逐票 Implement → Review
连规划和决策本身都无法装进一个会话,且路线仍然模糊:
Wayfinder → 逐个解决 Decision Ticket → Spec → Tickets → 逐票 Implement → Review
wayfinder 不是所有大功能的默认入口。只有决策工作本身需要多个会话时才使用;如果方向已经清楚,只是代码量大,直接进入 Spec 和 Tickets。
路径 D:存量项目治理
适合:老项目、架构腐化、Agent 经常走错目录或重复造轮子。
架构扫描 → 选一个高收益问题 → Grill → Spec/Tickets → Refactor → Review → 更新长期文档
一个简单判断标准:
| 当前状态 | 下一步 |
|---|---|
| 一个会话内可以澄清的需求 | Grill with Docs |
| 规划本身跨多个会话,路线仍然模糊 | Wayfinder |
| 有一个靠讨论无法回答的问题 | Prototype |
| 已决定,且一次会话能完成 | 直接 Implement |
| 已决定,但要跨多个会话 | Spec → Tickets |
| 已经有 Diff | Code Review |
| 整个项目持续让 Agent 迷路 | 架构扫描与长期文档治理 |
三、先学会调用:这些指令到底敲在哪里
安装命令在终端执行,Skill 指令在 Coding Agent 的聊天框执行,两者不要混淆。
3.1 首次安装
在项目根目录的终端执行:
npx skills@latest add mattpocock/skills
安装时至少选择:
setup-matt-pocock-skills
grill-with-docs
grilling
domain-modeling
wayfinder
prototype
handoff
to-spec
to-tickets
implement
code-review
improve-codebase-architecture
然后在 Agent 聊天框中初始化当前仓库:
/setup-matt-pocock-skills
Matt 的文档统一使用 /skill-name 表示调用。不同 Coding Agent 的显式调用语法可能不同;如果客户端没有对应的斜杠命令,直接点名 Skill 和任务即可。不要假定所有 Codex 客户端都支持同一种 $skill-name 语法。
/grill-with-docs 规划用户退款功能
使用 grill-with-docs skill 规划用户退款功能
如果客户端没有斜杠命令补全,直接点名 Skill 是最稳妥的写法。
3.2 Skill 指令的通用结构
不要只输入 Skill 名称。推荐写成:
/<skill> <处理对象>
目标:这一步想得到什么。
输入:应该读取哪些代码、文档、Issue 或当前对话。
边界:这一步不能做什么。
输出:结束时必须返回什么。
例如:
/grill-with-docs 规划退款功能。
目标:确认状态流转、幂等规则、权限和验收标准。
输入:先读取订单、支付、退款相关代码和现有文档。
边界:暂时不要实现,不要生成 Spec。
输出:分轮向我提问,并列出最终确认项和未决项。
3.3 四条路径的实际操作
路径 A:小型、明确任务
在当前会话直接执行:
/implement 当前任务已经明确,计划就在当前对话中:
1. 将登录按钮文案改为“立即登录”
2. 禁用颜色复用现有主题变量
3. 不修改登录流程
4. 完成后运行相关测试和类型检查
提交后,在干净的新会话中执行:
/code-review main
完整顺序:
/implement <明确任务>
→ 新会话
/code-review <分支起点>
极小的文案或样式修改也可以直接描述任务,不必强制调用 Skill。
路径 B:中型功能
先在当前会话执行:
/grill-with-docs 给商品列表增加价格区间筛选。
请先读取商品列表、查询参数、接口封装和现有筛选组件。
分轮确认筛选交互、URL 状态、默认值、边界情况和验收标准。
能从代码确认的内容不要问我,暂时不要实现。
回答完全部问题后,不清空当前上下文,继续执行:
/implement 使用刚才在当前对话中确认的方案直接实现。
实现完成后开启新会话:
/code-review main
完整顺序:
/grill-with-docs <功能>
→ 回答分轮问题
/implement 使用当前对话中的方案
→ 新会话
/code-review <分支起点>
路径 C:跨会话工作
先判断跨会话的是“实现”还是“规划”。
如果需求能在当前会话讨论清楚,只是实现量较大,仍然从 /grill-with-docs 开始:
在规划会话中依次执行:
/grill-with-docs 规划完整退款系统。
请先读取相关代码,分轮确认业务规则、状态、权限、异常恢复、幂等和验收标准。
暂时不要实现。
遇到一个无法仅靠讨论确认的问题时,才进入原型支线:
/handoff 为“退款状态机原型”生成交接文档,只保留原型所需上下文。
在新的原型会话中:
读取这份 handoff 文件,然后执行:
/prototype 验证重复申请、超时回调和人工审核并发发生时,
状态机是否可能产生重复退款。
只回答这个问题,不接真实接口,不修改生产代码。
把原型结论带回原规划会话,然后执行:
/to-spec 将当前对话已经确认的方案整理成 Spec。
不要发明未讨论过的需求,保留原型结论、测试接缝和范围外事项。
不要清空上下文,紧接着执行:
/to-tickets 把刚生成的 Spec 拆成 Agent 可独立完成的 Tickets。
每张 Ticket 必须能独立演示、适合一个上下文窗口,并标明依赖和验证命令。
发布前先把拆分方案给我确认。
确认 Ticket 后,每张 Ticket 使用一个干净会话:
/implement https://github.com/owner/repo/issues/42
开始前先复述标题、范围和验收标准,一次只实现这一张 Ticket。
全部完成后再做总审查:
/code-review main
完整顺序:
/grill-with-docs <大型功能>
→ 必要时 /handoff + /prototype
/to-spec
/to-tickets
→ 每张 Ticket 新会话:/implement <完整 Issue URL>
→ 最终新会话:/code-review <分支起点>
如果连需要作出哪些决策都不完全清楚,规划本身需要多个会话,则改用:
/wayfinder 描绘完整退款系统的决策地图。
目标:明确最终要到达的状态,并找出在进入实现前必须解决的决策。
边界:只规划和解决决策,不编写产品代码。
输出:建立决策地图、Decision Tickets、依赖关系和当前 Frontier。
随后在独立会话中逐个解决开放且未阻塞的 Decision Ticket。它们的产物是“决定”,不是实现代码。地图清空后执行:
/to-spec <完整的 Wayfinder Map 引用>
/to-tickets
→ 每张实现 Ticket 新会话:/implement <完整 Issue URL>
→ 最终新会话:/code-review <分支起点>
路径 D:存量项目治理
先扫描,不直接重构:
/improve-codebase-architecture
扫描当前代码库,寻找值得加深模块边界的架构问题。
先只生成候选报告,不修改代码,也不要直接选择第一个候选。
优先分析近期频繁修改和反复出错的区域。
看完报告后选择一个候选:
选择候选 2。针对它开始 Grill,确认目标边界、迁移约束、
需要保留的接口和测试接缝。仍然不要修改代码。
决策完成后回到主流程:
/to-spec
/to-tickets
→ 每张 Ticket:/implement <完整 Issue URL>
→ /code-review <分支起点>
四、阶段 1:Grill with Docs——有状态的领域建模访谈
4.1 它不只是澄清需求
grill-with-docs 是一个面向代码仓库、限定在单个规划会话内的有状态访谈。它同时完成两件事:
- 通过
grilling的决策树与 Frontier 机制,让你和 Agent 对方案形成共同理解; - 通过
domain-modeling在访谈过程中持续维护统一领域语言和重要决策记录。
它与普通 grill-me 最关键的区别是:结果不只留在对话中,还会在磁盘上留下经过筛选的长期知识。
默认行为既不是一次只问一个问题,也不是把所有问题一次抛完。每轮会提出当前 Frontier 上已经满足前置条件、彼此不依赖的问题;你的回答会解锁下一轮问题。问题总数不设固定上限,如果范围不断膨胀,应主动收窄任务或要求结束。
需要澄清四类内容:
- 目标:用户最终获得什么变化?
- 边界:哪些内容明确不做?
- 约束:兼容性、技术栈、上线时间、性能、安全要求是什么?
- 不稳定决策:哪些假设一旦错误,会导致大量返工?
可直接使用的开场提示:
请先不要实现。阅读与该需求相关的代码和文档,然后分轮向我提问,
帮助我明确目标、范围、约束、验收标准和仍未解决的关键决策。
能从仓库确认的信息不要问我。按照决策依赖分轮提问,
每个问题给出推荐答案及取舍。发现术语冲突或现有实现与需求矛盾时明确指出。
如果你个人更喜欢一次回答一个问题,可以在 AGENTS.md 或 CLAUDE.md 中配置:
When grilling, ask one question at a time.
这属于个人交互偏好,不是 Skill 默认机制。
4.2 Stateful:访谈过程中实时写回仓库
写文件不是会话结束后的人工整理步骤,而是 Skill 在访谈过程中自动执行的核心行为:
- 稳定的业务术语:写入
CONTEXT.md或项目已有的领域文档。 - 难以逆转、令人意外且存在真实取舍的决定:写入
docs/adr/。 - 只服务当前功能的细节:进入 Spec 或当前任务,不写入全局说明。
- 临时猜测、推导过程:留在会话中,不污染仓库。
单 Context 仓库默认使用根目录的 CONTEXT.md 和 docs/adr/。如果根目录存在 CONTEXT-MAP.md 并将项目标记为多 Context 仓库,术语应写入对应上下文自己的 CONTEXT.md。
CONTEXT.md 只保存项目词汇和紧凑定义,不应混入功能 Spec、实现细节或临时笔记。这也能避免 AGENTS.md 或 CLAUDE.md 变成所有历史问题的堆积场。
4.3 人负责决策和控制范围
Agent 负责发现事实、提出问题和推荐方案,但不能替你作出产品与设计决定。使用者需要主动:
- 质疑问题的前提和推荐答案;
- 阻止问题扩展到当前目标之外;
- 要求重新打开被错误关闭的决策分支;
- 识别需要 Prototype 的高保真问题;
- 判断什么时候已经达到共同理解并允许结束。
连续回答“同意”并不等于有效 Grill。规划阶段更依赖模型的参数化知识来发现你没有想到的问题,因此值得使用能力较强的模型;进入上下文充分的实现阶段后,才更适合考虑较小模型。
4.4 完成标准与故障信号
CONTEXT.md在访谈过程中随着术语确认逐条变化,而不是结束时一次性生成。CONTEXT.md保持为纯词汇表,没有 Spec 和实现细节。- Agent 使用项目自己的业务名词,而不是泛化命名。
- “不做什么”已经明确。
- 每个关键决策都有确定答案,或被标记为需要 Prototype。
- 代码中能确认的内容没有被反问给用户。
- 结束前 Agent 会要求你确认双方已经形成共同理解,而不是自动开始实现。
一次会话只让词汇表更清晰、没有生成任何 ADR,完全可能是正常结果;大多数功能决定不满足 ADR 的三个门槛。
如果出现下面情况,先检查 Skill 是否正确加载,而不是继续追加提示词:
- 所有问题一次性抛出;
- 问题没有推荐答案;
- 全程不提
CONTEXT.md; - 访谈正常,但没有任何领域文档变化。
可直接要求:
停止当前 Grill。说明本次实际加载了哪些 Skills,
并确认 grilling 和 domain-modeling 是否都已加载。
五、阶段 2:Prototype——用一次性代码回答一个问题
5.1 什么时候需要原型
只有满足下面条件才值得原型化:
存在一个具体、重要的问题,而且仅靠继续讨论无法可靠回答。
典型问题:
- 页面采用抽屉还是分步流程,哪种信息层级更清楚?
- 状态机在返回、刷新和重复回调时是否正确?
- 长连接断线重连是否会造成事件重复?
- 某个 SDK 在目标平台上是否真的支持所需能力?
如果问题是“已经实现的功能为什么坏了”,应该诊断 Bug,而不是做 Prototype。
5.2 原型的约束
原型只为学习服务,因此通常不要添加:
- 完整错误处理;
- 持久化数据库;
- 预防未来需求的抽象;
- 生产级测试和兼容层;
- 与核心问题无关的 UI 美化。
推荐模板:
# Prototype Question
## 要回答的问题
在用户重复提交并返回上一页时,当前状态机是否会产生两个有效订单?
## 成功标准
- 可以复现正常、重复提交、请求超时三个场景
- 每一步显示完整状态
- 产品或开发无需阅读代码即可操作
## 明确不做
- 不接真实支付接口
- 不实现正式 UI
- 不写入生产数据库
5.3 两类原型
逻辑或状态原型:建议做成单个可打开的 HTML;核心逻辑保持为纯函数、Reducer 或状态机,页面显示当前完整状态并提供场景化操作按钮。
UI 原型:一次至少展示多个结构明显不同的方案。变化应体现在信息架构和交互,而不只是颜色、圆角和文案。尽量放入真实页面壳和接近真实的数据密度中。
5.4 如何保存原型结论
原型代码不合并进主分支,但也不必彻底删除:
prototype/<question-name> 分支:保存可重新运行的证据
正式任务或 ADR:保存问题、结论和原型分支链接
main:只接收基于结论重新实现的生产代码
如果原型超过一天还没有回答问题,通常说明问题范围太大,需要继续切小。
六、阶段 3:Handoff——只在上下文真的需要移动时使用
Handoff 不是普通总结,也不是所有阶段结束后的固定动作。它的价值是可移植性。
适合四种情况:
- 从 Claude Code 切换到 Codex、Cursor 等另一套工具;
- 移动到新的目录或原型仓库;
- 把工作交给同事;
- 保留当前主会话,同时把支线问题交给另一个执行者。
同一工具、同一目录、同一任务继续工作时,优先继续会话或做上下文压缩,不必 Handoff。
Handoff 文档模板
# Handoff:验证订单状态机
## 目标
通过最小原型确认重复提交和超时恢复时的状态转移。
## 已确认事实
- 当前 Web 端入口:`src/pages/order/...`
- 服务端以 idempotencyKey 去重
## 尚未确认
- 客户端返回上一页后是否复用旧 key
## 本次任务
只实现可操作的状态机原型,不修改生产代码。
## 约束
- 不连接真实接口
- 不引入新的状态管理库
## 相关资料
- Spec:`docs/specs/order-submit.md`
- ADR:`docs/adr/003-idempotency.md`
## 完成后返回
- 一句话结论
- 能复现结论的操作步骤
- 原型分支或文件路径
已经存在于 Spec、ADR、Issue 和代码中的内容只引用路径,不要重复复制,否则会产生两个可能漂移的事实源。交接前还要检查:推测是否被误写成事实,文件中是否含 Token、密码或用户隐私。
七、阶段 4:Spec——记录已经作出的决定
7.1 什么时候写 Spec
Spec 的唯一硬触发条件是:
方向已经确定,但实现将跨越多个 Agent 会话,需要让决定在上下文结束后继续存在。
如果任务一次会话能完成,直接实现即可。每个小修改都写 Spec,不仅浪费 Token,还会增加一次模型转述造成的漂移。
7.2 Spec 不应该继续发明需求
to-spec 的输入来自:
- 刚完成的澄清对话;
- 仓库代码;
CONTEXT.md;- ADR;
- 原型验证结论。
它的职责是合成已有决定,而不是重新采访或自动补全产品需求。Spec 中出现一个从未讨论过的确定性要求,就是缺陷。
7.3 推荐 Spec 模板
# 功能名称
## 背景与目标
为什么做;完成后用户或系统获得什么变化。
## 已确认决策
- 决策及原因
- 原型验证结论与引用
## 范围
- 本次包含
- 本次明确不包含
## 业务规则与状态
- 正常路径
- 边界状态
- 失败和恢复路径
## 现有系统接缝
- 从哪个入口触发
- 通过哪个接口或模块完成
- 尽量复用哪些现有边界
## 验收标准
- 可观察、可测试的结果
- 每项都能追踪到已确认需求
## 风险与发布
- 兼容性、迁移、灰度、回滚和监控
7.4 先确认测试接缝
写长篇说明前,先确认功能在哪个边界上被验证。例如:
- 纯函数或 Reducer;
- API handler;
- 页面级集成测试;
- 跨端通信协议;
- H5 ↔ Native JSBridge 协议。
优先选择现有且最高层的稳定接缝,数量越少越好。重点人工审查 Out of Scope 和测试接缝,因为这里出错的返工成本最高。
八、阶段 5:Tickets——按可演示的垂直切片拆分
8.1 不要按技术层拆
错误示例:
- 创建数据库表;
- 实现全部 API;
- 实现全部页面;
- 最后补测试。
这些 Ticket 单独结束时没有完整可用结果,验收标准互相跨越,集成风险被推到最后。
推荐按 Tracer Bullet 拆分:每张 Ticket 是穿过必要层次的一条窄路径,可以独立运行、演示和验收。
示例:梦境记录功能可以拆成:
- 用户创建一条纯文本梦境并在列表看到它;
- 用户编辑已有梦境,刷新后内容仍存在;
- 用户请求 AI 解析并看到加载、成功与失败状态;
- 用户从解析结果生成分享卡片。
每张票可能同时涉及 Schema、API、UI 和测试,但都能独立说明“完成后可以演示什么”。
8.2 Ticket 模板
# 用户可创建并查看纯文本梦境
## 价值
完成后用户可以保存梦境,并立即在历史列表中看到。
## 范围
- 表单输入与校验
- 创建接口
- 列表展示
- 对应测试
## 不包含
- AI 解析
- 图片上传
- 分享卡片
## 验收标准
- 空内容无法提交
- 创建成功后列表立即出现记录
- 刷新页面后记录仍存在
- API 失败时保留输入并显示错误
## Demo Path
登录 → 新建梦境 → 输入内容 → 保存 → 在列表中打开
## 依赖
无 / Blocked by #xx
## 验证命令
pnpm lint
pnpm test -- dream-create
pnpm build
8.3 大范围重构的例外
跨全项目的字段或公共类型迁移很难拆成正常垂直切片,可以使用 Expand–Migrate–Contract:
- Expand:增加新接口,同时保留旧接口,CI 仍然通过;
- Migrate:按包、目录或业务域分批迁移调用方;
- Contract:所有调用方迁移后删除旧接口。
如果某张 Ticket 完成后回答不了“现在可以演示什么”,它多半仍是横向切片。
九、阶段 6:安全执行——让 Agent 自主,但不要失控
无论使用 Codex Worktree、Docker、Podman、云沙箱还是 Sandcastle,后台执行都至少需要:
- 明确且足够小的任务范围;
- 隔离分支或 Worktree;
- 可见日志;
- 自动验证命令;
- 以 Commit 或 Diff 返回结果;
- 不自动发布、不自动改生产环境;
- 第二轮独立审查的入口。
9.1 最小执行提示模板
实现 Ticket #12,只处理 Ticket 定义的范围。
开始前:
1. 阅读 Ticket、相关 Spec、项目指令文件(`AGENTS.md` / `CLAUDE.md`)和涉及目录的代码。
2. 复述验收标准与验证命令;如果信息冲突,停止并报告。
实现时:
1. 优先复用现有结构,不顺手重构无关区域。
2. 每完成一个可验证节点就运行最小测试。
3. 不修改生产配置,不提交密钥,不执行发布操作。
结束时:
1. 运行 lint、测试和构建。
2. 汇报改动、验证结果、残余风险和未完成项。
3. 生成一个范围清晰的提交,等待审查。
9.2 Sandcastle 可选方案
Sandcastle 是 TypeScript 编排库,可把 Agent 放入 Docker、Podman 或 Vercel 沙箱,管理分支并回收提交。快速开始:
npm install --save-dev @ai-hero/sandcastle
npx @ai-hero/sandcastle init
npx tsx .sandcastle/main.ts
典型配置:
import { run, codex } from "@ai-hero/sandcastle";
import { docker } from "@ai-hero/sandcastle/sandboxes/docker";
const result = await run({
agent: codex("gpt-5.4"),
sandbox: docker(),
promptFile: ".sandcastle/prompt.md",
branchStrategy: {
type: "branch",
branch: "agent/dream-create",
},
maxIterations: 3,
});
console.log(result.commits);
这只是可选的执行基础设施。独立 Git 分支或 Worktree 加人工审查通常已经够用;需要多个 AFK Agent、统一日志或实现—审查流水线时,再引入 Sandcastle。
十、阶段 7:Code Review——分开回答两个问题
审查必须明确区分两个轴:
| 审查轴 | 核心问题 | 主要依据 |
|---|---|---|
| Standards | 代码写得对不对? | 项目规范、既有模式、架构约束、代码异味 |
| Spec | 做的是不是正确的东西? | Spec、Ticket、验收标准、明确的范围外事项 |
一份符合所有代码规范、却实现错需求的代码,Standards 可以通过,但 Spec 必须失败;反过来也一样。不要用一个综合分数让其中一项掩盖另一项。
10.1 审查提示模板
审查当前分支相对 main 的 Diff,不要直接修改代码。
分别输出两部分:
1. Standards Review
- 对照仓库规范与现有实现模式
- 检查不必要重复、错误抽象、跨层耦合和维护风险
- 跳过已经由 Linter 可靠覆盖的问题
2. Spec Review
- 对照 Ticket/Spec 的每项验收标准
- 找出遗漏、部分实现、实现错误和范围膨胀
每条发现必须包含:严重级别、证据位置、违反的依据、影响和最小修复建议。
如果没有证据,不要提出推测性问题。
最佳实践是让一个干净的新会话审查,避免编写代码的同一上下文替自己确认。每张 Ticket 完成后审查一次,整个功能合并前再相对分支起点做一次全局审查。
Agent 的审查结论仍然只是待验证的假设。执行修复前,要核对它引用的代码和需求依据是否真实存在。
十一、阶段 8:让一次错误改善下一次运行
Agent 出现可避免错误时,不要只问“换更强模型是否能解决”,而要做一次根因分类:
| 错误类型 | 应改进的位置 |
|---|---|
| 误解业务词语 | CONTEXT.md 或领域文档 |
| 忘记长期稳定规则 | 最小化后的 AGENTS.md、CLAUDE.md 或技术 Skill |
| 漏掉当前需求 | Spec 或 Ticket |
| 不知道如何确认成功 | 验收标准、测试或 CI |
| 多次在同一模块绕路 | 模块接口、目录边界或架构 |
| 仅本次偶发推理错误 | 修复当前代码,不急着增加规则 |
长期规则只有在满足以下条件时才值得进入 AGENTS.md、CLAUDE.md 或 Skill:
- 下个月仍然成立;
- 会影响多项任务;
- 仓库本身无法轻易推断;
- 不与 Linter、类型系统或已有文档重复;
- 能写成明确、可操作、可验证的规则。
否则,规则越积越多会消耗上下文,并产生冲突和过时约束。
十二、完整 Demo:从模糊需求到完成审查
下面以“为任务管理应用增加到期提醒”为例,完整走一次大型任务流程。重点不是功能本身,而是观察每个 Skill 如何衔接。
12.1 起点:只有一句模糊需求
原始想法:
给任务增加提醒功能。
不要直接让 Agent 开发,先执行:
/grill-with-docs 给任务管理应用增加到期提醒。
先读取任务模型、创建和编辑流程、通知能力及现有文档。
通过分轮问题帮我确认提醒的触发规则、时区、重复任务、修改任务后的处理、
权限、失败恢复和验收标准。暂时不要实现。
12.2 Grill 的示例交互
Agent 第一轮可能问:
1. 提醒时间由用户单独设置,还是根据截止时间自动计算?
A. 单独设置(推荐):灵活,但多一个输入项
B. 截止前固定 30 分钟:简单,但不够灵活
C. 同时支持:体验完整,但首版范围更大
2. 用户修改截止时间时,已有提醒如何处理?
A. 保持相对间隔自动移动(推荐)
B. 保持原绝对时间
C. 删除并要求重新设置
用户回答:
1 选 A,提醒是独立时间,但必须早于截止时间。
2 选 B,提醒保持原绝对时间;如果新的截止时间早于提醒时间,要求用户重新选择。
首版不支持重复任务,也不做短信,只做应用内通知。
继续回答后,最终应得到类似结论:
已确认:
- 每个任务最多一个提醒
- 提醒使用用户选择的绝对时间
- 数据统一存 UTC,展示使用用户时区
- 修改截止时间造成提醒无效时阻止保存
- 只做应用内通知
范围外:
- 重复任务
- 邮件和短信
- 多次提醒
未决问题:
- 跨夏令时切换时,用户看到的本地时间是否符合预期
12.3 对未知问题做 Prototype
夏令时问题难以靠口头确认,于是创建支线:
/handoff 为“提醒时间与夏令时原型”生成交接文档。
只保留时间存储、展示和修改所需的上下文。
在新会话执行:
/prototype 验证提醒跨越夏令时切换时的行为。
唯一问题:用户选择“每天当地时间 09:00”的语义,
与存储一个绝对 UTC 时间的结果是否一致?
提供三个可操作场景并显示本地时间、时区和 UTC 值。
不接数据库,不实现正式 UI。
原型给出结论:一次性提醒存绝对 UTC 即可;“每天 09:00”属于重复提醒语义,本期不做。把这一结论返回规划会话。
12.4 生成 Spec
/to-spec 将当前对话确认的到期提醒方案写成 Spec。
必须包括:
- 一次性提醒的数据语义
- UTC 存储与本地展示
- 修改截止时间时的校验
- 应用内通知的失败处理
- 测试接缝
- 明确的范围外事项
- prototype/reminder-dst 原型结论
不得加入重复提醒、短信或邮件通知。
人工重点检查:
- Spec 是否把“每个任务最多一个提醒”写成了验收条件;
- 是否擅自增加了重复提醒;
- 测试接缝是否落在现有任务服务和通知调度器边界;
Out of Scope是否完整。
12.5 拆 Tickets
/to-tickets 把提醒功能 Spec 拆成垂直 Tickets。
每张 Ticket 都必须:
- 能独立演示
- 同时包含所需的数据、逻辑、界面和测试
- 适合一个新会话完成
- 写明 Demo Path、依赖和验证命令
发布前先展示拆分方案。
合理的拆分可能是:
- 用户创建任务时可以设置一个提醒,并在详情页看到;
- 用户编辑或删除提醒,刷新后结果保持;
- 到达提醒时间后用户收到应用内通知;
- 修改截止时间导致提醒无效时阻止保存并给出提示;
- 调度失败能够重试并留下可观察记录。
错误拆法则是:先建表、再写接口、再写页面、最后补测试。因为每张票单独完成时都没有可演示能力。
12.6 实现第一张 Ticket
新建目标分支或 Worktree,然后开启干净会话:
/implement https://github.com/example/tasks/issues/101
开始前先确认:
- Ticket 标题
- 范围和范围外
- 测试接缝
- 验证命令
一次只实现 #101,不顺便实现后续通知调度。
Agent 应当读取 Ticket,按确认的接缝编写测试,反复运行局部测试和类型检查,最后运行完整测试并产生一个范围清楚的提交。
完成后人工检查、关闭 Ticket,再用新的会话执行下一张:
/implement https://github.com/example/tasks/issues/102
12.7 独立审查
每张 Ticket 可以单独审查。所有 Ticket 完成后,再开一个不含实现过程的新会话:
/code-review main
审查当前分支相对 main 的全部改动。
分别报告 Standards 和 Spec 两个维度,不要把它们合并评分。
每条发现必须引用具体代码和对应规范或 Spec 条目。
只审查,不直接修改。
如果审查发现“修改截止时间后没有验证提醒时间”,这是 Spec 符合度问题;如果功能正确但绕过项目既有任务服务直接访问数据库,则是 Standards 问题。
12.8 把错误反馈到正确位置
假设 Agent 把所有本地时间直接写入数据库,需要区分:
- Spec 已明确 UTC,而 Agent 漏做:修复代码和当前 Ticket。
- Spec 没有写清时间语义:修复 Spec/Ticket 生成流程。
- 项目多个功能都反复混用时间:在长期文档中补充稳定时间约定,或封装统一时间模块。
最终闭环不是“这次修好了”,而是“下一次更难犯同类错误”。
十三、一页执行清单
开始前
- 任务目标是否一句话说得清?
- 范围外事项是否明确?
- Agent 是否先读取了相关代码?
- 是否存在只能通过运行或看见才能回答的问题?
规划时
- 一次会话是否足以完成?足够则跳过 Spec/Tickets。
- Spec 是否只记录已作出的决定?
- 测试接缝是否明确?
- 每张 Ticket 是否能独立演示?
- 依赖关系是否真实而非人为串行?
执行时
- 是否在隔离分支、Worktree 或沙箱中?
- 是否限制修改范围和权限?
- 日志和验证结果是否可见?
- 是否禁止自动部署和生产环境变更?
审查后
- Standards 和 Spec 是否分别检查?
- 审查发现是否都有代码或文档证据?
- 错误来自代码、任务、文档、验证还是架构?
- 哪些经验值得长期保存,哪些只应留在本次任务?
十四、最终原则
- 先减少不确定性,再提高生成速度。
- Prototype 只回答一个问题,不负责变成产品。
- Spec 是已确认决策的快照,不是让 AI 发明需求的模板。
- Ticket 按可独立演示的垂直能力拆分。
- 自主执行必须以隔离、可观察和可审查为前提。
- 代码规范与需求符合度必须分开审查。
- 一次 Agent 错误,应优先改善系统,而不是无限堆规则或直接换模型。
- 工作流按任务规模裁剪;能简单解决的问题,不要仪式化。
- Grill 辅助工程师作出决定,不替代工程师;人必须主动控制范围和确认结论。
- 实现跨会话使用 Spec/Tickets,规划本身跨会话且路线模糊才使用 Wayfinder。
参考资料
- setup-matt-pocock-skills
- grilling
- domain-modeling
- grill-with-docs
- wayfinder
- prototype
- handoff
- to-spec
- to-tickets
- code-review
- improve-codebase-architecture
- Sandcastle
注:本文不是逐字翻译,而是基于邮件课程与下钻文档提炼、纠偏后形成的工程实践版本。